package authorization

import (
	"gitee.com/liangziyisheng/caas-platform-mc/internal/consts"

	"github.com/casbin/casbin/v2"
	"github.com/casbin/casbin/v2/model"
	"github.com/goflyfox/gtoken/gtoken"
	_ "github.com/gogf/gf/contrib/drivers/mysql/v2"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
	"github.com/gogf/gf/v2/os/gctx"
	adapter "github.com/hailaz/gf-casbin-adapter/v2"
)

var localEnforcer *casbin.Enforcer
var l = g.Log("logger for authorization")

func init() {

	// 初始化enforcer
	m := model.NewModel()
	m.AddDef("r", "r", "sub,obj,act")
	m.AddDef("p", "p", "sub,obj,act")
	m.AddDef("g", "g", "_,_")
	m.AddDef("e", "e", "some(where (p.eft == allow))")
	m.AddDef("m", "m", "g(r.sub, p.sub) && keyMatch2(r.obj,p.obj) && r.act == p.act")

	// m.AddDef("m", "m", "g(r.sub, p.sub) && keyMatch(r.obj,p.obj) && r.act == p.act")
	a := adapter.NewAdapter(adapter.Options{GDB: g.DB("casbin"), TableName: "t_casbin_rule"})
	e, err := casbin.NewEnforcer(m, a)
	if err != nil {
		panic(err)
	}
	e.LoadPolicy()
	localEnforcer = e
}

func NewEnforcer() *casbin.Enforcer {
	if localEnforcer != nil {
		localEnforcer.LoadPolicy()
	}
	return localEnforcer
}

// CasbinMiddleware is a middleware that checks the permission of the user.
func CasbinMiddleware(r *ghttp.Request) {
	e := localEnforcer
	ctx := gctx.New()
	l.Info(ctx, r.URL.Path, r.Method)
	userIdStr := r.GetCtxVar(consts.TokenClaims.UserId).String()
	ok, err := e.Enforce(userIdStr, r.URL.Path, r.Method)
	if err != nil {
		panic(err)
	}
	if !ok {
		r.Response.WriteJson(gtoken.Fail("无权限"))
		return
	}
	r.Middleware.Next()
}
